package org.example.day07;

import java.util.ArrayList;
import java.util.List;

/**
 * 第三章节3.1.6: 使用wait/notify实现线程销毁
 *      注意：线程B执行notify后并没有释放锁，直到执行完同步代码块
 *           线程A被唤醒后并没有立即执行，等执行notify的线程B执行完同步代码块后，才会开始执行
 */
public class MyThread5 {
    private static List list = new ArrayList<>();
    public static void add(){
        list.add("anything");
    }
    public static int size(){
        return list.size();
    }

    public static void main(String[] args) {
        try {
            Object o = new Object();
            Thread5A ta = new Thread5A(o);
            ta.start();
            Thread.sleep(50); //确保A线程先拿到锁
            Thread5B tb = new Thread5B(o);
            tb.start();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class Thread5A extends Thread{
    private Object lock;

    public Thread5A(Object lock) {
        this.lock = lock;
    }

    @Override
    public void run() {
        try {
            synchronized (lock){
                if(MyThread5.size() != 5){
                    System.out.println("wait begin = " + System.currentTimeMillis());
                    lock.wait(); //释放锁
                    System.out.println("wait end = " + System.currentTimeMillis());
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class Thread5B extends Thread{
    private Object lock;

    public Thread5B(Object lock) {
        this.lock = lock;
    }

    @Override
    public void run() {
        try {
            synchronized (lock){
                for (int i = 0; i < 10; i++) {
                    MyThread5.add();
                    if(MyThread5.size() == 5){
                        lock.notify();
                        System.out.println("唤醒操作已发出");
                    }
                    System.out.println("添加了" + (i+1) + "个元素");
                    Thread.sleep(1000);
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
